feat(extractors): add GDScript (.gd) + Godot scene/resource (.tscn/.t… - #1929
feat(extractors): add GDScript (.gd) + Godot scene/resource (.tscn/.t…#1929ozdemirsarman wants to merge 3 commits into
Conversation
…res/project.godot) extraction
|
I think you can use |
Address review (Graphify-Labs#1929): depend on tree-sitter-language-pack>=1.12.5,<1.13 (as Graphify-Labs#1836 does) instead of the unpublished tree-sitter-gdscript wheel. The .gd extractor loads the bundled gdscript grammar; the scene/resource extractor now uses the bundled godot_resource grammar, falling back to a dependency-free line parser when the extra is absent.
|
Done — switched the godot extra to tree-sitter-language-pack>=1.12.5,<1.13 (matching #1836). Both grammars now come from the pack: .gd uses gdscript, and I also moved the .tscn/.tres/project.godot scene extractor onto the bundled godot_resource grammar (with a dependency-free line-parser fallback when the extra isn't installed). The pack only needs tree-sitter>=0.23, so it stays within the repo's <0.26 pin. Tests pass. |
|
Thanks for the quick update! seems to be usable as is now. Looks like you have claude working on this, if that's the case: any thoughts on implementing the other file changes as with #1836?
I'd also consider the following nits (coming from #1835 as well):
The naming of the "godot scene" I think should be changed to "godot resource", meaning a bit of changes in the code itself to reference this. |
Address review (Graphify-Labs#1929): depend on tree-sitter-language-pack>=1.12.5,<1.13 (as Graphify-Labs#1836 does) instead of the unpublished tree-sitter-gdscript wheel. The .gd extractor loads the bundled gdscript grammar; the scene/resource extractor now uses the bundled godot_resource grammar, falling back to a dependency-free line parser when the extra is absent.
Address review (Graphify-Labs#1929): depend on tree-sitter-language-pack>=1.12.5,<1.13 (as Graphify-Labs#1836 does) instead of the unpublished tree-sitter-gdscript wheel. The .gd extractor loads the bundled gdscript grammar; the scene/resource extractor now uses the bundled godot_resource grammar, falling back to a dependency-free line parser when the extra is absent.
…yze/build/MIGRATION, README + fixtures (Graphify-Labs#1929) - Register .gd (gdscript) and .tscn/.tres/project.godot (godot_resource) in analyze.py, build.py and extractors/MIGRATION.md, matching Graphify-Labs#1836. - Rename the scene extractor to godot_resource (module, extract_godot_resource, registry key, wiring) per review. - Shrink the pyproject godot comment to one line. - README: add a godot extras row and split the godot file types into their own GDScript / Godot resources rows. - Move the inline gdscript/godot test bodies into tests/fixtures/godot/ and rename the test file to test_godot_resource.py.
|
Thanks for the review! Addressed everything in
Full suite green locally. Let me know if you'd like the |
…ify-Labs#1929 Vendors tests/fixtures/godot verbatim from PR Graphify-Labs#1929 (feat/gdscript-godot-extractor, commit de0f6b2), which added them alongside the extractor; only the README is local. Our tests were all tmp_path-inline, so we had no fixtures at all. resource/ is a Godot project in miniature - project.godot registering an autoload and a main scene, a .tscn attaching a script and instancing another scene, and the scripts they name. That cross-file shape is the point: both Godot id defects (duplicate file nodes, and a cross-file stub evicting the file it names) needed several files referencing each other, and neither is reachable from a single-file test. Two assertions over it: every file resolves to exactly one canonically named node, and every attaches_script / instances / main_scene / script edge lands on a node that exists.
Add GDScript + Godot scene/resource extraction
Adds first-class support for Godot Engine projects: GDScript (
.gd) ASTextraction plus a grammar-free extractor for Godot's scene/resource/project
text formats (
.tscn,.tres,project.godot). This closes the gap where aGodot codebase currently contributes almost nothing to the graph.
What's new
GDScript (
.gd) —graphify/extractors/gdscript.py(tree-sitter-gdscript)class_name Foo/ innerclass Foodefinesextends Bar/extends "res://x.gd"extendsedge (res:// resolved)func f(): …definesfoo()/obj.method()in a bodycallsedges (local funcs resolved)Autoload.method()callsedge resolved to the function in the autoload's script (autoload map read fromproject.godot)signal s(args)declaresemit_signal("s")/s.emit()emitsedges.connect(handler)connectsedge (handler resolved to local func)preload("res://y.gd")/load(...)importsedge (res:// resolved)Godot scenes/resources/project —
graphify/extractors/godot_scene.py(no grammar; line parser)[ext_resource type="Script" path="res://x.gd"]attaches_scriptedge[ext_resource type="PackedScene" path="res://y.tscn"]instancesedgescript = ExtResource("id")on a nodeattaches_script[connection signal="s" from="A" to="." method="m"]connectsedge, resolved to the target script's function nodeproject.godot [autoload]autoload+scriptedgesproject.godot run/main_scenemain_sceneedgeThe scene
[connection]→ function resolution is the payoff Godot devs can'tget from GDScript-only tooling: signal wires defined in
.tscnfiles linkstraight to the handler
funcin the.gdfile, because both sides mint thesame
_make_id(script_stem, method)node id.Wiring (mirrors every other language)
graphify/extractors/gdscript.py,graphify/extractors/godot_scene.py(new)detect.py:.gd .tscn .tres .godotadded toCODE_EXTENSIONSextract.py: facade re-exports +_DISPATCHentriesextractors/__init__.py:LANGUAGE_EXTRACTORSregistry entriespyproject.toml: optionalgodot = ["tree-sitter-gdscript"]extraREADME.md: language table updatedGraceful degradation
Both extractors are safe without the grammar.
.gdreturns a bare file nodewhen tree-sitter-gdscript is absent (same pattern as
sql/pascal), and thescene extractor needs no grammar at all — so scene/autoload/signal-wire edges
always work.
Tests
tests/test_gdscript.py(skipped when the grammar is absent) andtests/test_godot_scene.py(always runs) cover every relation above, plus theregistry-identity sweep in
test_extractors_registry.pyauto-covers the two newregistry entries. All fixtures are synthetic; no third-party project code.
Open question for maintainers — grammar packaging
tree-sitter-gdscript(PrestonKnopp, MIT) is not yet published to PyPI as astandalone wheel, though its repo ships working Python bindings and builds from
source cleanly. The
.gdloader therefore triestree_sitter_gdscriptfirstand falls back to a grammar from
tree-sitter-language-pack. I'm happy to (a)publish
tree-sitter-gdscriptto PyPI with proper attribution, or (b) switchthe
godotextra to whatever dependency you prefer — let me know. The.tscnhalf needs no grammar regardless.